import React from 'react';
import {Switch, Route, Redirect} from "react-router-dom";

const RouteWithProps = ({path, exact, strict, render, location, ...rest}) => (
  <Route
    path={path}
    exact={exact}
    strict={strict}
    location={location}
    render={props => render({...props, ...rest})}
  />
);

const withRoutes = (route) => {
  const {Routes} = route;
  let len = Routes.length - 1;
  let Component = args => {
    const {render, ...props} = args;
    return render(props)
  };
  while (len >= 0) {
    const AuthRoute = Routes[len];
    const OldComponent = Component;
    Component = props => (
      <AuthRoute {...props}>
        <OldComponent {...props}/>
      </AuthRoute>
    );
    len -= 1;
  }
  return args => {
    const {render, ...rest} = args;
    return (
      <RouteWithProps
        {...rest}
        render={props => {
          return <Component {...props} route={route} render={render}/>
        }}
      />
    )
  };
};


export default function renderRoutes(
  routes,
  extraProps = {},
  switchProps = {},
) {
  return routes ? (
    <Switch {...switchProps}>
      {routes.map((route, i) => {
        if (route.redirect) {
          return (
            <Redirect
              key={route.key || i}
              from={route.path}
              to={route.redirect}
              exact={route.exact}
              strict={route.strict}
            />
          );
        }
        const RouteRoute = route.Routes ? withRoutes(route) : RouteWithProps;
        return (
          <RouteRoute
            key={route.key || i}
            path={route.path}
            exact={route.exact}
            strict={route.strict}
            render={props => {
              const childRoutes = renderRoutes(
                route.routes,
                {},
                {
                  location: props.location,
                },
              );
              if (route.component) {
                return (
                  <route.component {...props} route={route}>
                    {childRoutes}
                  </route.component>
                )
              } else {
                return childRoutes;
              }
            }}
          />
        )

      })}

    </Switch>
  ) : null;
}



